from typing import List, NoReturn

try:
    from .boxdrawing import BoxDrawing
    from .entities import *
    from .event import Event
    from .grid import Block
    from .player import Player
    from .randoms import random_board
except:
    from boxdrawing import BoxDrawing  # type: ignore
    from entities import *  # type: ignore
    from event import Event  # type: ignore
    from grid import Block  # type: ignore
    from player import Player  # type: ignore
    from randoms import random_board  # type: ignore

__all__ = ['Board']


class Board:
    def __init__(self, board: List[List[Block]] = None):
        self.board: List[List[Block]] = board if board is not None else random_board(
            ((River, 0.1), (Mountain, 0.1), (Tree, 0.03)))
        self._width = len(self.board)
        self._height = len(self.board[0]) if self._width else 0
        for c in range(self._width):
            for r in range(self._height):
                self.board[c][r].board = self
                self.board[c][r].position = (c, r)

    def print(self):
        print(str(self))

    def __str__(self):
        ret = BoxDrawing.getChar(top=True, left=True) + \
            BoxDrawing.getChar(midhor=True) * (self._width * 2) + \
            BoxDrawing.getChar(top=True, right=True) + '\n'
        for r in range(self._height):
            ret += BoxDrawing.getChar(midver=True)
            for c in range(self._width):
                ret += str(self.board[c][r])
            ret += BoxDrawing.getChar(midver=True) + '\n'
        ret += BoxDrawing.getChar(left=True, bottom=True) + \
            BoxDrawing.getChar(midhor=True) * (self._width * 2) + \
            BoxDrawing.getChar(right=True, bottom=True)
        return ret

    def event_trigger(self, ev: Event) -> NoReturn:
        """Call this when an event is triggered.

        Args:
            - `ev` (`Event`): The triggered event.
        """
        for c in range(self._width):
            for r in range(self._height):
                self.board[c][r].event_trigger(ev)

    def __getitem__(self, i):
        return self.board.__getitem__(i)


if __name__ == '__main__':
    b = Board(random_board(((River, 0.1), (Mountain, 0.1), (Tree, 0.03)), 20, 20))
    b.board[10][10].append(Warrior())
    b.board[10][10].append(Lab(Player(), Wood))
    b.print()
